

public class Compiler{
	
	
	private  Tokenizer tkn;
	Compiler(Tokenizer tkn){
		this.tkn = tkn;
	}
	//e=> t+t | t-t | t
	public int expression(){
		int ret = 0;
		ret = term();
		while(tkn.hasNext()){
			if(tkn.match(StateType.MINUS)){
				ret -= term();
			}else if(tkn.match(StateType.PLUS)){
				ret += term();
			}else{
				break;
			}
		}
		return ret;
	}
	//t=> sf*f | sf/f | sf %f | f
	public int term(){
		int ret = 0;
		ret = sfactor();
		while(tkn.hasNext()){
			if(tkn.match(StateType.MULTIPLY)){
				ret *= sfactor();
			}else if(tkn.match(StateType.DIVIDE)){
				ret /= sfactor();
			}else if(tkn.match(StateType.MOD)){
				ret %= sfactor();
			}else{
				break;
			}
		}
		return ret;
	}
	//sf=>+ f | -f | f
	public int sfactor(){
		int ret = 0;
		if(tkn.match(StateType.AND)){
			ret = factor();
		}else if(tkn.match(StateType.MINUS)){
			ret = - factor();
		}else{
			ret = factor();
		}
		return ret;
	}
	//f=>i | (e)
	public int factor(){
		int ret = 0;
		Token t = tkn.nextToken();
		if(t.type == StateType.LPARENT){
			ret = expression();
			t = tkn.nextToken();
			if(t.type != StateType.RPARENT){
				System.out.println("syntax wrong there must be )");
			}
		}else if(t.type == StateType.INTEGER || t.type == StateType.FLOAT){
			ret = (Integer)t.value;
		}else{
			System.out.println("syntax wrong there must be a number or (");
		}
		return ret;
	}
	/**
	 * Method main
	 *
	 *
	 * @param args
	 *
	 */
	public static void main(String[] args) {
		String test = " ((1 * -(1+ 3) + 3 - 2 +4) - 8/2)*4";
		Tokenizer tkn = new Tokenizer(test);
		Compiler cp = new Compiler(tkn);
		int ret = cp.expression();
		System.out.println("result is " + ret);
	}	
}
